package com.itcast.flink.sources.socket;

import com.itcast.flink.sources.socket.pojo.OrderPayment;
import com.itcast.flink.sources.socket.repository.OrderPaymentRepository;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * <p>Description: </p>
 * @date 
 * @author 
 * @version 1.0
 * <p>Copyright:Copyright(c)2020</p>
 */
@SpringBootApplication
@ComponentScan(basePackages = {"com.itcast"})
@EnableTransactionManagement
public class OrderPaymentApplication {


    /**
     *  订单状态信息
     */
    private static Integer[] orderStatus = new Integer[]{0, 1, 2};




    /**
     * netty服务端的启动
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
        ConfigurableApplicationContext applicationContext = SpringApplication.run(OrderPaymentApplication.class, args);
        while(true) {
            // 获取订单缓存信息
            Set<String> orderCache = getOrderCache(applicationContext);
            Set<String> filterCache = new HashSet<>();
            for(String orderInfo : orderCache) {
                String[] orderInfoArr = orderInfo.split(",");
                OrderPayment orderPayment = new OrderPayment();
                // 设置订单信息
                orderPayment.setOrderId(Long.valueOf(orderInfoArr[0]));
                orderPayment.setUserId(Long.valueOf(orderInfoArr[1]));
                Random random = new Random();
                int randStatus = random.nextInt(orderStatus.length);
                orderPayment.setStatus(randStatus);
                if(randStatus == 0) {
                    // 未支付
                    orderPayment.setUpdateTime(Long.valueOf(orderInfoArr[2]));
                }else if(randStatus == 1) {
                    // 已支付（10秒内）
                    orderPayment.setUpdateTime(Long.valueOf(orderInfoArr[2]) + 10000);
                    filterCache.add(orderInfo);
                }else if(randStatus == 2) {
                    // 已取消(默认延时3秒）
                    orderPayment.setUpdateTime(Long.valueOf(orderInfoArr[2]) + 3000);
                    filterCache.add(orderInfo);
                }
               // 保存订单支付信息
               OrderPaymentRepository orderPaymentRepository = (OrderPaymentRepository)applicationContext.getBean("orderPaymentRepository");
               orderPaymentRepository.save(orderPayment);
                // 写入间隔时间
                Thread.sleep(1000l);
            }
            // 更新缓存信息
            clearCache(applicationContext, orderCache, filterCache);
            // 循环间隔时间
            Thread.sleep(1000l);
        }

    }

    /**
     * 清除缓存
     * @param applicationContext
     * @return
     */
    private static void clearCache(ConfigurableApplicationContext applicationContext,
                                   Set<String> orderCache, Set<String> filterCache) {
        CacheManager cacheManager = (CacheManager)applicationContext.getBean("cacheManager");
        Cache cache = cacheManager.getCache("orderCache");
        orderCache.removeAll(filterCache);
        if(orderCache.size() > 0 ) {
            // 更新缓存
            cache.put("orderIds", orderCache);
        }else {
            // 清空缓存
            cache.clear();
        }
    }

    /**
     * 获取订单缓存信息
     * @param orderResult
     * @param applicationContext
     */
    private static Set<String> getOrderCache(ConfigurableApplicationContext applicationContext) {

        CacheManager cacheManager = (CacheManager)applicationContext.getBean("cacheManager");
        Cache cache = cacheManager.getCache("orderCache");
        Cache.ValueWrapper orderWrapper = cache.get("orderIds");
        if(null != orderWrapper) {
            Set<String> orderIds = (Set<String>)orderWrapper.get();
            return orderIds;
        }
        return new HashSet<>();
    }


}
